﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Framework.Entidade.Acesso;
using System.Configuration;
using System.Data;
using Framework.Util.Enumerador;
using Framework.Util;

namespace Framework.AcessoDados.Acesso
{
    public class AD_Funcionalidade
    {
        #region Construtor

        public EN_Funcionalidade Construtor(SqlDataReader dr)
        {
            if (dr == null) { throw new ArgumentNullException("reader"); }

            int id = dr.GetOrdinal("id");
            int idPai = dr.GetOrdinal("idPai");
            int titulo = dr.GetOrdinal("titulo");
            int descricao = dr.GetOrdinal("descricao");
            int resumo = dr.GetOrdinal("resumo");
            int destino = dr.GetOrdinal("destino");
            int tipo = dr.GetOrdinal("tipo");
            int ordem = dr.GetOrdinal("ordem");
            int corMenu = dr.GetOrdinal("corMenu");
            int status = dr.GetOrdinal("status");

            EN_Funcionalidade objFuncionalidade = new EN_Funcionalidade();

            //Recuperando campos do retorno do objeto
            if (!dr.IsDBNull(id))
            {
                objFuncionalidade.Id = dr.GetInt32(id);
            }
            if (!dr.IsDBNull(idPai))
            {
                objFuncionalidade.IdPai = dr.GetInt32(idPai);
            }
            if (!dr.IsDBNull(titulo))
            {
                objFuncionalidade.Titulo = dr.GetString(titulo);
            }
            if (!dr.IsDBNull(descricao))
            {
                objFuncionalidade.Descricao = dr.GetString(descricao);
            }
            if (!dr.IsDBNull(resumo))
            {
                objFuncionalidade.Resumo = dr.GetString(resumo);
            }
            if (!dr.IsDBNull(destino))
            {
                objFuncionalidade.Destino = dr.GetString(destino);
            }
            if (!dr.IsDBNull(tipo))
            {
                objFuncionalidade.Tipo = dr.GetString(tipo);
            }
            if (!dr.IsDBNull(ordem))
            {
                objFuncionalidade.Ordem = dr.GetInt32(ordem);
            }
            if (!dr.IsDBNull(corMenu))
            {
                objFuncionalidade.CorMenu = dr.GetString(corMenu);
            }
            if (!dr.IsDBNull(status))
            {
                objFuncionalidade.Status = dr.GetBoolean(status);
            }

            return objFuncionalidade;
        }

        #endregion

        #region Métodos

        /// <summary>
        /// Método responsável pela listagem de todos os Funcionalidades já cadastrados conforme filtro
        /// </summary>
        /// <param name="idPai">Id Pai da Funcionalidade</param>
        /// <param name="titulo">Título da Funcionalidade</param>
        /// <param name="status">Status da Funcionalidade</param>
        /// <returns>Lista de Objetos EN_Funcionalidade preenchidos</returns>
        public List<EN_Funcionalidade> Listar(int idPai, string titulo, string status)
        {
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["FrameworkConnectionDev"].ConnectionString;

            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;

            string where = string.Empty;
            int count = 0;

            if (idPai > 0)
            {
                where += " AND idPai = @idPai ";
                cmd.Parameters.Add("@idPai", SqlDbType.Int);
                cmd.Parameters[count].Value = idPai;
                count++;
            }
            if (!string.IsNullOrEmpty(titulo))
            {
                where += " AND titulo LIKE @titulo ";
                cmd.Parameters.Add("@titulo", SqlDbType.VarChar, 50);
                cmd.Parameters[count].Value = string.Concat("%", titulo, "%");
                count++;
            }
            if (!string.IsNullOrEmpty(status))
            {
                if (status != StatusEnum.T.ToString())
                {
                    status = status == StatusEnum.A.ToString() ? "True" : "False";

                    where += " AND (status = @status) ";
                    cmd.Parameters.Add("@status", SqlDbType.Bit);
                    cmd.Parameters[count].Value = status;
                }
            }

            cmd.CommandText = string.Format(@"SELECT id, idPai, titulo, descricao, resumo, destino, tipo, ordem, corMenu, status FROM ACE_Funcionalidade WHERE (1 = 1) {0} order by idPai, ordem ", where);

            EN_Funcionalidade objFuncionalidade = new EN_Funcionalidade();
            List<EN_Funcionalidade> lstFuncionalidades = new List<EN_Funcionalidade>();

            try
            {
                conn.Open();
                SqlDataReader dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    objFuncionalidade = this.Construtor(dr);
                    lstFuncionalidades.Add(objFuncionalidade);
                }

                conn.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return lstFuncionalidades;
        }

        /// <summary>
        /// Método responsável pela listagem das Funcionalidades associadas ao Grupo
        /// </summary>
        /// <param name="idGrupo">Id do Grupo</param>
        /// <param name="status">Status da Funcionalidade</param>
        /// <returns>Lista de Objetos EN_Funcionalidade preenchidos</returns>
        public List<EN_Funcionalidade> ListarFuncionalidadePorGrupo(int idGrupo, string status)
        {
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["FrameworkConnectionDev"].ConnectionString;

            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;

            string where = string.Empty;
            int count = 0;

            if (idGrupo > 0)
            {
                where += " AND gf.idGrupo = @idGrupo ";
                cmd.Parameters.Add("@idGrupo", SqlDbType.Int);
                cmd.Parameters[count].Value = idGrupo;
                count++;
            }
            if (!string.IsNullOrEmpty(status))
            {
                if (status != StatusEnum.T.ToString())
                {
                    status = status == StatusEnum.A.ToString() ? "True" : "False";

                    where += " AND (f.status = @status) ";
                    cmd.Parameters.Add("@status", SqlDbType.Bit);
                    cmd.Parameters[count].Value = status;
                }
            }

            cmd.CommandText = string.Format(@"select f.id, f.idPai, f.titulo, f.descricao, f.resumo, f.destino, f.tipo, f.ordem, f.status, f.corMenu
                                                from ACE_GrupoFuncionalidade gf
                                                inner join ACE_Funcionalidade f on f.id = gf.idFuncionalidade
                                                where f.status = 'True'
                                                {0} 
                                                order by f.idPai, f.ordem", where);

            EN_Funcionalidade objFuncionalidade = new EN_Funcionalidade();
            List<EN_Funcionalidade> lstFuncionalidades = new List<EN_Funcionalidade>();

            try
            {
                conn.Open();
                SqlDataReader dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    objFuncionalidade = this.Construtor(dr);
                    lstFuncionalidades.Add(objFuncionalidade);
                }

                conn.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return lstFuncionalidades;
        }

        /// <summary>
        /// Método responsável pela listagem de todos os Funcionalidades já cadastrados conforme filtro
        /// </summary>
        /// <param name="status">Status da Funcionalidade</param>
        /// <returns>Lista de Objetos EN_Funcionalidade preenchidos</returns>
        public List<EN_Funcionalidade> ListarPrincipais(string status)
        {
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["FrameworkConnectionDev"].ConnectionString;

            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;

            string where = string.Empty;

            if (!string.IsNullOrEmpty(status))
            {
                if (status != StatusEnum.T.ToString())
                {
                    status = status == StatusEnum.A.ToString() ? "True" : "False";

                    where += " AND (status = @status) ";
                    cmd.Parameters.Add("@status", SqlDbType.Bit);
                    cmd.Parameters[0].Value = status;
                }
            }

            cmd.CommandText = string.Format(@"SELECT id, idPai, titulo, descricao, resumo, destino, tipo, ordem, corMenu, status FROM ACE_Funcionalidade WHERE (idPai = 0) {0} order by idPai, ordem ", where);

            EN_Funcionalidade objFuncionalidade = new EN_Funcionalidade();
            List<EN_Funcionalidade> lstFuncionalidades = new List<EN_Funcionalidade>();

            try
            {
                conn.Open();
                SqlDataReader dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    objFuncionalidade = this.Construtor(dr);
                    lstFuncionalidades.Add(objFuncionalidade);
                }

                conn.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return lstFuncionalidades;
        }

        /// <summary>
        /// Método responsável pelo retorno da Funcionalidade desejado
        /// </summary>
        /// <param name="id">id da Funcionalidade</param>
        /// <param name="destino">Destino da Funcionalidade</param>
        /// <returns>Objeto EN_Funcionalidade preenchido</returns>
        public EN_Funcionalidade RetornarFuncionalidade(int id, string destino)
        {
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["FrameworkConnectionDev"].ConnectionString;

            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;

            string where = string.Empty;
            int count = 0;

            if (id > 0)
            {
                where += " AND id = @id ";
                cmd.Parameters.Add("@id", SqlDbType.Int);
                cmd.Parameters[count].Value = id;
                count++;
            }
            if (!string.IsNullOrEmpty(destino))
            {
                where += " AND (destino = @destino) ";
                cmd.Parameters.Add("@destino", SqlDbType.VarChar);
                cmd.Parameters[count].Value = destino;
            }

            cmd.CommandText = string.Format(@"SELECT id, idPai, titulo, descricao, resumo, destino, tipo, ordem, corMenu, status FROM ACE_Funcionalidade WHERE (1 = 1) {0} ", where);

            EN_Funcionalidade objFuncionalidade = new EN_Funcionalidade();

            try
            {
                conn.Open();
                SqlDataReader dr = cmd.ExecuteReader();

                if (dr.Read())
                {
                    objFuncionalidade = this.Construtor(dr);
                }

                conn.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return objFuncionalidade;
        }

        /// <summary>
        /// Método responsável por Salvar o Funcionalidade no Banco de Dados
        /// Insere ou Altera
        /// </summary>
        /// <param name="objFuncionalidade">Objeto Funcionalidade preenchido</param>
        /// <param name="conn">Objeto SqlConnection</param>
        /// <param name="trans">Objeto SqlTransaction</param>
        /// <returns>Id da Funcionalidade</returns>
        public int Salvar(EN_Funcionalidade objFuncionalidade, SqlConnection conn, SqlTransaction trans)
        {
            int idFuncionalidade = 0;

            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;

            cmd.Parameters.Add("@idPai", SqlDbType.Int);
            cmd.Parameters[0].Value = objFuncionalidade.IdPai;

            cmd.Parameters.Add("@titulo", SqlDbType.VarChar, 50);
            cmd.Parameters[1].Value = objFuncionalidade.Titulo;

            cmd.Parameters.Add("@descricao", SqlDbType.VarChar, 100);
            cmd.Parameters[2].Value = objFuncionalidade.Descricao;

            cmd.Parameters.Add("@resumo", SqlDbType.VarChar);
            cmd.Parameters[3].Value = objFuncionalidade.Resumo;

            cmd.Parameters.Add("@destino", SqlDbType.VarChar, 250);
            cmd.Parameters[4].Value = objFuncionalidade.Destino;

            cmd.Parameters.Add("@tipo", SqlDbType.Char, 3);
            cmd.Parameters[5].Value = objFuncionalidade.Tipo;

            cmd.Parameters.Add("@ordem", SqlDbType.Int);
            cmd.Parameters[6].Value = objFuncionalidade.Ordem;

            cmd.Parameters.Add("@corMenu", SqlDbType.VarChar, 50);
            cmd.Parameters[7].Value = objFuncionalidade.CorMenu;

            cmd.Parameters.Add("@status", SqlDbType.Bit);
            cmd.Parameters[8].Value = objFuncionalidade.Status;

            if (objFuncionalidade.Id == 0)
            {
                cmd.CommandText = @"INSERT INTO ACE_Funcionalidade
                                                (idPai, titulo, descricao, resumo, destino, tipo, ordem, corMenu, status)
                                            VALUES
                                                (@idPai, @titulo, @descricao, @resumo, @destino, @tipo, @ordem, @corMenu, @status)
        
                                    SELECT @@identity";
            }
            else
            {
                cmd.CommandText = @"UPDATE ACE_Funcionalidade
                                        SET idPai = @idPai
                                            ,titulo = @titulo
                                            ,descricao = @descricao
                                            ,resumo = @resumo
                                            ,destino = @destino
                                            ,tipo = @tipo
                                            ,ordem = @ordem
                                            ,corMenu = @corMenu
                                            ,status = @status
                                        WHERE id = @id
        
                                    SELECT @id";

                cmd.Parameters.Add("@id", SqlDbType.Int);
                cmd.Parameters[9].Value = objFuncionalidade.Id;
            }

            try
            {
                cmd.Transaction = trans;
                idFuncionalidade = Convert.ToInt32(cmd.ExecuteScalar());
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return idFuncionalidade;
        }

        /// <summary>
        /// Método responsável por Excluir/Inativar o Funcionalidade desejado
        /// </summary>
        /// <param name="id">id da Funcionalidade</param>
        /// <param name="conn">Objeto SqlConnection</param>
        /// <param name="trans">Objeto SqlTransaction</param>
        public void Excluir(int id, SqlConnection conn, SqlTransaction trans)
        {
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;

            cmd.CommandText = @"UPDATE ACE_Funcionalidade
                                SET status = 'False'
                                WHERE id = @id";

            cmd.Parameters.Add("@id", SqlDbType.Int);
            cmd.Parameters[0].Value = id;

            try
            {
                cmd.Transaction = trans;
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion
    }
}
